package com.fitbet.wechat.web.controller.profile;

import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import com.demo2do.core.entity.exception.BusinessException;
import com.demo2do.core.entity.result.HttpResult;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.utils.WebUtils;
import com.demo2do.core.wechat.entity.cfg.JsConfig;
import com.fitbet.entity.bet.Bet;
import com.fitbet.entity.bet.UserBet;
import com.fitbet.entity.bet.UserBetStatus;
import com.fitbet.entity.bet.UserBetSupport;
import com.fitbet.entity.bet.UserBetSupportStatus;
import com.fitbet.entity.user.User;
import com.fitbet.entity.user.UserTransaction;
import com.fitbet.entity.user.Wallet;
import com.fitbet.wechat.processor.WechatProcessor;
import com.fitbet.wechat.service.BetService;
import com.fitbet.wechat.service.UserBetService;
import com.fitbet.wechat.service.UserTransactionService;
import com.fitbet.wechat.service.WalletService;
import com.fitbet.wechat.web.interceptor.UserContext;
import com.fitbet.wechat.web.interceptor.UserContextType;
import com.fitbet.wechat.web.resolver.Secure;

/**
 * 
 * @author mohanlan
 *
 */
@Controller
@RequestMapping("/profile")
public class ProfileController {

    private static final Logger logger = LoggerFactory.getLogger(ProfileController.class);

    @Autowired
    private BetService betService;

    @Autowired
    private UserBetService userBetService;

    @Autowired
    private WalletService walletService;

    @Autowired
    private WechatProcessor wechatProcessor;

    @Autowired
    UserTransactionService userTransactionService;
    
    /**
     * 个人中心首页
     * 
     * @author LZJ
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @UserContext(type = UserContextType.WECHAT_AUTHORITY)
    public ModelAndView index(@Secure User user, HttpServletRequest request) {

        ModelAndView modelAndView = new ModelAndView("profile/profile");
        modelAndView.addObject("user", user);

        Wallet wallet = walletService.loadWallet(user.getUnionid());

        modelAndView.addObject("personal", user);
        modelAndView.addObject("wallet", wallet);

        String curl = WebUtils.getRealRequestURL(request);
        JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
        modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));

        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param request
     * @return
     */
    @RequestMapping(value = "/bill", method = RequestMethod.GET)
    @UserContext(type = UserContextType.WECHAT_AUTHORITY)
    public ModelAndView bill(@Secure User user, HttpServletRequest request) {
        
        ModelAndView modelAndView = new ModelAndView("profile/profile-bill");
        modelAndView.addObject("user", user);
        
        // TODO list all user transaction order by time 降序;
        List<UserTransaction> userTransactions = userTransactionService.list();
        modelAndView.addObject("userTransactions", userTransactions);
        
        String curl = WebUtils.getRealRequestURL(request);
        JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
        modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));
        
        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param request
     * @return
     */
    @RequestMapping(value = "/withdrawal", method = RequestMethod.GET)
    @UserContext(type = UserContextType.WECHAT_AUTHORITY)
    public ModelAndView withdrawal(@Secure User user, HttpServletRequest request) {
        
        ModelAndView modelAndView = new ModelAndView("profile/withdrawal-index");
        modelAndView.addObject("user", user);
        
        Wallet wallet = walletService.loadWallet(user.getUnionid());

        modelAndView.addObject("personal", user);
        modelAndView.addObject("wallet", wallet);
        
        String curl = WebUtils.getRealRequestURL(request);
        JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
        modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));

        return modelAndView;
    }
    
    /**
     * 
     * @param user
     * @param price
     * @return
     */
    @RequestMapping(value = "/withdrawal", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onWithdrawal(@Secure User user, @RequestParam("price") int price, @RequestParam("content") String content) {
        
        HttpResult httpResult = new HttpResult();
        
        try {
            
            userTransactionService.createTransaction(user,price,content);
            return httpResult.success().message("提现成功");
            
        } catch (Exception e) {
            logger.error("onCreateUserBet error: ", e);
            throw BusinessException.newInstance("500", "提现失败");
        }
    }

    /**
     * 我（参与/投注）的活动
     * 
     * @author LZJ
     * @param type
     * @return
     */
    @RequestMapping(value = "/bets", method = RequestMethod.GET)
    @UserContext(type = UserContextType.WECHAT_AUTHORITY)
    public ModelAndView bets(@Secure User user, @RequestParam(value = "type", required = false,
            defaultValue = "participate") String type, HttpServletRequest request) {

        ModelAndView modelAndView = new ModelAndView("profile/profile-bet-" + type);
        modelAndView.addObject("user", user);

        if ("participate".equals(type)) {
            // 获取我参与的活动列表
            // 根据用户找到对应自己的活动
            List<UserBet> userBets = userBetService.list(user.getId(),
                    new UserBetStatus[] {UserBetStatus.PAID, UserBetStatus.OPEN,
                            UserBetStatus.OPENFAILED, UserBetStatus.CLOSE, UserBetStatus.OPENFAILED,
                            UserBetStatus.PROCESSING, UserBetStatus.FINISHED});
            
            modelAndView.addObject("userBets", userBets);
        } else {
            // 获取我投注的活动列表
            // 根据用户查询投注的活动
            List<UserBetSupport> userBetSupports =
                    userBetService.listUserBetSupport(user.getId(), new UserBetSupportStatus[] {
                            UserBetSupportStatus.PAID, UserBetSupportStatus.FINISHED});
            modelAndView.addObject("userBetSupports", userBetSupports);
        }

        String curl = WebUtils.getRealRequestURL(request);
        JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
        modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));

        return modelAndView;
    }

    /**
     * 创建user bet
     * 
     * @param user
     * @param betId
     * @return
     */
    @RequestMapping(value = "/bets", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onCreateUserBet(@Secure User user,
            @RequestParam("betId") Long betId) {

        HttpResult httpResult = new HttpResult();

        try {

            Bet bet = betService.loadBet(betId);
            Map<String, Object> data = userBetService.createUserBet(user, bet);
            return httpResult.success().data(data);
        } catch (Exception e) {
            logger.error("onCreateUserBet error: ", e);
            throw BusinessException.newInstance("500", "创建数据失败");
        }
    }

    /**
     * 我参与的bet详情
     * 
     * @param user
     * @param betId
     * @return
     */
    @RequestMapping(value = "/bets/{betId}", method = RequestMethod.GET)
    @UserContext(type = UserContextType.WECHAT_AUTHORITY)
    public ModelAndView betDetail(@Secure User user, @PathVariable(value = "betId") Long betId,
            HttpServletRequest request) {

        // 判断是否有结束审核按钮
        ModelAndView modelAndView = new ModelAndView("profile/profile-bet-detail");
        modelAndView.addObject("user", user);

        UserBet userBet = userBetService.loadUserBet(user.getId(), betId,
                new UserBetStatus[] {UserBetStatus.PROCESSING, UserBetStatus.PAID,
                        UserBetStatus.OPEN, UserBetStatus.OPENFAILED, UserBetStatus.CLOSE,
                        UserBetStatus.CLOSEFAILED, UserBetStatus.FINISHED});

        // 已支付，跳转到待开启，开启审核，开启失败页面
        if (userBet.getStatus().equals(UserBetStatus.PAID)) {
            modelAndView.setViewName("redirect:/profile/bets/" + betId + "/open");
            return modelAndView;
        }

        modelAndView.addObject("userBet", userBet);

        List<UserBetSupport> supports = userBetService.listSupports(userBet);
        modelAndView.addObject("supports", supports);

        String curl = WebUtils.getRealRequestURL(request);
        JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
        modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));

        return modelAndView;
    }

    /**
     * 
     * @param user
     * @param betId
     * @return
     */
    @RequestMapping(value = "/bets/{betId}/open", method = RequestMethod.GET)
    public ModelAndView betOpen(@Secure User user, @PathVariable(value = "betId") Long betId,
            HttpServletRequest request) {

        ModelAndView modelAndView = new ModelAndView("profile/profile-bet-open");
        modelAndView.addObject("user", user);

        UserBet userBet = userBetService.loadUserBet(user.getId(), betId,
                new UserBetStatus[] {UserBetStatus.PROCESSING, UserBetStatus.PAID,
                        UserBetStatus.OPEN, UserBetStatus.OPENFAILED, UserBetStatus.CLOSE,
                        UserBetStatus.CLOSEFAILED, UserBetStatus.FINISHED});
        
        // 已支付，跳转到待开启，开启审核，开启失败页面
        if (userBet.getStatus().equals(UserBetStatus.PROCESSING)
                || userBet.getStatus().equals(UserBetStatus.FINISHED)
                || userBet.getStatus().equals(UserBetStatus.OPEN)
                || userBet.getStatus().equals(UserBetStatus.OPENFAILED)
                || userBet.getStatus().equals(UserBetStatus.CLOSEFAILED)) {
            modelAndView.setViewName("redirect:/profile/bets/" + betId);
            return modelAndView;
        }

        modelAndView.addObject("userBet", userBet);

        String curl = WebUtils.getRealRequestURL(request);
        JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
        modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));

        return modelAndView;
    }

    /**
     * 开启user bet
     * 
     * @param user
     * @param betId
     * @return
     */
    @RequestMapping(value = "/bets/{betId}/open", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onOpenBet(@Secure User user, @PathVariable("betId") Long betId,
            @RequestParam("weight") Float beforeWeight,
            @RequestParam("beforeVedio") String beforeVedio) {

        HttpResult httpResult = new HttpResult();

        try {

            UserBet userBet = userBetService.openUserBet(user.getId(), betId, beforeWeight, beforeVedio);
            return httpResult.success().message("开启挑战成功").data("userBet", userBet);

        } catch (Exception e) {
            logger.error("onCreateUserBet error: ", e);
            throw BusinessException.newInstance("500", "开启挑战失败");
        }
    }

    /**
     * 
     * @param user
     * @param betId
     * @return
     */
    @RequestMapping(value = "/bets/{betId}/close", method = RequestMethod.GET)
    public ModelAndView betClose(@Secure User user, @PathVariable(value = "betId") Long betId,
            HttpServletRequest request) {

        ModelAndView modelAndView = new ModelAndView("redirect:/profile/bets/" + betId);
        modelAndView.addObject("user", user);

        UserBet userBet = userBetService.loadUserBet(user.getId(), betId,
                new UserBetStatus[] {UserBetStatus.PROCESSING, UserBetStatus.PAID,
                        UserBetStatus.OPEN, UserBetStatus.OPENFAILED, UserBetStatus.CLOSE,
                        UserBetStatus.CLOSEFAILED, UserBetStatus.FINISHED});
        
        // 已支付，跳转到待开启，开启审核，开启失败页面
        if (userBet.getStatus().equals(UserBetStatus.PROCESSING) && userBet.getBet().isEnd()) {
            modelAndView.setViewName("profile/profile-bet-close");
            modelAndView.addObject("userBet", userBet);

            String curl = WebUtils.getRealRequestURL(request);
            JsConfig jsConfig = wechatProcessor.generateJsConfig(curl);
            modelAndView.addObject("jsConfig", JsonUtils.toJson(jsConfig));
            
            return modelAndView;
        }
        
        return modelAndView;
    }

    /**
     * 开启user bet
     * 
     * @param user
     * @param betId
     * @return
     */
    @RequestMapping(value = "/bets/{betId}/close", method = RequestMethod.POST,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public @ResponseBody HttpResult onCloseBet(@Secure User user, @PathVariable("betId") Long betId,
            @RequestParam("weight") Float afterWeight,
        @RequestParam("afterVedio") String afterVedio) {

        HttpResult httpResult = new HttpResult();

        try {

            UserBet userBet = userBetService.closeUserBet(user.getId(), betId, afterWeight, afterVedio);
            return httpResult.success().message("开启挑战成功").data("userBet", userBet);

        } catch (Exception e) {
            logger.error("onCreateUserBet error: ", e);
            throw BusinessException.newInstance("500", "开启挑战失败");
        }
    }
}
